package com.visionet.waveletData.web.service.plan;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.visionet.waveletData.web.common.security.password.RequestSignUtil;
import com.visionet.waveletData.web.common.utilities.props.PropsKeys;
import com.visionet.waveletData.web.common.utilities.props.PropsUtil;
import com.visionet.waveletData.web.common.utils.PageInfo;
import com.visionet.waveletData.web.entity.group.Group;
import com.visionet.waveletData.web.entity.plan.PlayPlan;
import com.visionet.waveletData.web.repository.group.GroupDao;
import com.visionet.waveletData.web.repository.group.RobotGroupDao;
import com.visionet.waveletData.web.repository.plan.PlanFileDao;
import com.visionet.waveletData.web.repository.plan.PlanGroupDao;
import com.visionet.waveletData.web.repository.plan.PlayPlanDao;
import com.visionet.waveletData.web.repository.plan.specs.PlayPlanSearchspecs;
import com.visionet.waveletData.web.repository.robot.RobotDao;
import com.visionet.waveletData.web.service.BaseService;
import com.visionet.waveletData.web.service.ServiceException;
import com.visionet.waveletData.web.vo.SysPlanDataVo;
import com.visionet.waveletData.web.vo.plan.PlanGroupVo;
import com.visionet.waveletData.web.vo.plan.PlayPlanVo;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TreeMap;

@Service
public class PlayPlanService extends BaseService{

	private static final Logger logger = LoggerFactory.getLogger(PlayPlanService.class);

	private static final String curdPlayPlanPath = PropsUtil.getProperty(PropsKeys.playPlanCURDPath);

	@Resource
	private PlayPlanDao playPlanDao;

	@Resource
	private RobotGroupDao robotGroupDao;

	@Resource
	private PlanGroupDao planGroupDao;

	@Resource
	private RobotDao robotDao;

	@Resource
	private PlanFileDao planFileDao;

	@Resource
	private GroupDao groupDao;
	/**
	 * 根据id查询播放计划
	 * @param id
	 * @return
	 */
	public PlayPlan findPlayPlanById(Long id){
	      return playPlanDao.findOne(id);
		}
	/**
	 * 根据条件查询播放计划
	 * @param playPlan
	 * @return
	 */
	public Page<PlayPlan> findPlayPlanByConditionForList(PlayPlan playPlan,PageInfo pageInfo){
		PageRequest pageRequest = null;
		if(pageInfo==null){
			pageInfo = new PageInfo();
			pageInfo.setPageSize(5000);
		}
		pageRequest=this.getPageRequestInfo(pageInfo);
		Page<PlayPlan> page = playPlanDao.findAll(PlayPlanSearchspecs.searchTeamByCondition(playPlan),pageRequest);
		pageInfo.setTotalCount(page.getNumberOfElements());
		return page;

	}
	public Page<PlayPlanVo> findPlayPlanPage(PlayPlanVo playPlanVo,PageInfo page){
		if(playPlanVo == null){
            throw new NullPointerException("查询实体为空！！！");
        }
        PageInfo pageInfo = playPlanVo.getPageInfo();
        PageRequest pageRequest = null;
        if(playPlanVo.getPageInfo()==null){
            pageInfo = new PageInfo();
            pageInfo.setPageSize(10);
        }
        pageRequest=getPageRequestInfo(pageInfo);
		return playPlanDao.findPagePlayPlan(playPlanVo, pageRequest);
	}

	@Transactional(readOnly = false)
	public void deletePlayPlan(Long id){
		PlayPlan playPlan = playPlanDao.findPlayPlanById(id);
		if(null == playPlan){
			throw new ServiceException("播放计划不存在");
		}
		try {
            List<String> s = new ArrayList<>();
			List<PlanGroupVo> list = planGroupDao.findPlanGroupVoByPlanId(playPlan.getId().toString());
			for(PlanGroupVo planGroupVo : list){
				Group group =  groupDao.getOne(Long.parseLong(planGroupVo.getGroupId()));
                if(group != null){
                    group.setInPlanId(null);
                    groupDao.save(group);
                }
                s.add(planGroupVo.getId().toString());
			}
            planGroupDao.deletePlanGroup(s);
			playPlan.setIs_deleted("1");
			playPlanDao.save(playPlan);
		}catch (Exception e){
			throw new RuntimeException("删除播放计划异常：" + e.getMessage());
		}

	}

	@Transactional(readOnly = false)
	public Long savePlanPlan(PlayPlan playPlan){
		return playPlanDao.save(playPlan).getId();
	}

	public PageRequest getPageRequestInfo(PageInfo pageInfo) {
		Sort sort = new Sort(Direction.ASC, "id");
		return new PageRequest(pageInfo.getPageNumber() - 1,pageInfo.getPageSize(), sort);

	}
	public void updatePlayPlan(PlayPlanVo playPlanVo){
		if(playPlanVo.getId()==null){
			throw new ServiceException("id is null!");
		}
		PlayPlan playPlan = playPlanDao.findPlayPlanById(playPlanVo.getId());
		playPlan.setPlanName(playPlanVo.getPlanName());
		playPlanDao.save(playPlan);

		curdPlanData(playPlan.getId());
	}


	public List<PlayPlan> findAll(){
		return playPlanDao.findAll();
	}

	public List<PlayPlan> findByPlanName(String planName,String planId){
		return playPlanDao.findByPlanNameAndCompanyId(planName,planId);
	}
	public List<PlayPlan> findByPlanNameAndPlanId(String planName,Long planId){
		return playPlanDao.findByPlanNameAndPlanId(planName, planId);
	}

	/**
	 * 核心平台请求同步接口
	 * @param lastUpdateDate 上次更新时间
	 * @return
	 */
	public List<SysPlanDataVo> getSysPlanDateVos(Date lastUpdateDate, int pageIndex, int pageSize){
		long startTime = System.currentTimeMillis();
		try {
			List<SysPlanDataVo> sysPlanDateVoList = new ArrayList<>();
			//根据播放计划ID查询出所有播放计划
			PageInfo pageInfo = new PageInfo(pageIndex,pageSize);
			List<PlayPlan> planIdList = playPlanDao.findAllPlanIdByUpdateDate(lastUpdateDate,getPageRequestInfo(pageInfo));
			//迭代播放计划分组集合
			for(PlayPlan playPlan : planIdList){
				Long planId = playPlan.getId();
				SysPlanDataVo sysPlanDataVo = new SysPlanDataVo();
				sysPlanDataVo.setPlanId(planId.toString());
				sysPlanDataVo.setUpdateDate(playPlan.getUpdateDate());
				sysPlanDataVo.setCreateDate(playPlan.getCreateDate());
				sysPlanDataVo.setCompanyId(playPlan.getCompanyId());
				sysPlanDataVo.setPlanName(playPlan.getPlanName());
				if("1".equals(playPlan.getIs_deleted())){
					sysPlanDataVo.setIsDeleted(true);
				}else{
					sysPlanDataVo.setIsDeleted(false);
					sysPlanDataVo.setRobotList(robotDao.findAllRobotByPlanId(planId));
					sysPlanDataVo.setVideoList(planFileDao.findPlanFileByPlanId(planId.toString()));
				}
				sysPlanDateVoList.add(sysPlanDataVo);
			}
			long endTime = System.currentTimeMillis();
			System.out.println("请求播放列表数据耗时：" + (endTime - startTime) +"ms");
			return sysPlanDateVoList;
		}catch (Exception e){
			e.printStackTrace();
			throw new RuntimeException("查询同步播放计划失败" + e.getMessage());
		}

	}

	@Async
	public void curdPlanData(Long planId){
		logger.info("播放计划被修改，开始同步请求=========================================================");
		try {
			PlayPlan playPlan = playPlanDao.findOne(planId);
			SysPlanDataVo sysPlanDataVo = new SysPlanDataVo();
			if(playPlan != null){
				sysPlanDataVo.setPlanId(planId.toString());
				sysPlanDataVo.setUpdateDate(playPlan.getUpdateDate());
				sysPlanDataVo.setCreateDate(playPlan.getCreateDate());
				sysPlanDataVo.setCompanyId(playPlan.getCompanyId());
				sysPlanDataVo.setPlanName(playPlan.getPlanName());
				if("1".equals(playPlan.getIs_deleted())){
					sysPlanDataVo.setIsDeleted(true);
				}else{
					sysPlanDataVo.setIsDeleted(false);
					sysPlanDataVo.setRobotList(robotDao.findAllRobotByPlanId(planId));
					sysPlanDataVo.setVideoList(planFileDao.findPlanFileByPlanId(planId.toString()));
				}

				//开始组装签名
				StringBuffer params = new StringBuffer();
				TreeMap<String,String> treeMap = new TreeMap<>();
				treeMap.put("playPlan",JSONObject.toJSONString(sysPlanDataVo));
				String sign = RequestSignUtil.createCurdPlayPlanSign(treeMap);
				for (String key : treeMap.keySet()) {
					String value = treeMap.get(key);
					if(StringUtils.isNotBlank(value)){
						params.append(key);
						params.append("=");
						params.append(value);
						params.append("&");
					}
				}
				params.append("system").append("=").append(sign);
				String result = sendRequest(params.toString(), curdPlayPlanPath);
				JSONObject jsonObject = JSON.parseObject(result);
				if(jsonObject.getString("messageCode").equals("10000")){
					logger.info("同步成功=========================================================");
				}else{
					logger.info("同步失败=========================================================");
				}
			}
		} catch (Exception e){
			e.printStackTrace();
			logger.info("同步失败=========================================================");
		}
		logger.info("同步结束=========================================================");
	}


	//发送post请求
	@SuppressWarnings("unused")
	private String sendRequest(String params,String url){
		HttpURLConnection conn = null;
		OutputStreamWriter out = null;
		BufferedReader in = null;
		StringBuffer result = new StringBuffer();
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			conn = (HttpURLConnection) realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestMethod("POST");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setDoOutput(true);
			conn.setDoInput(true);
			//设置连接超时30s
			conn.setConnectTimeout(30000);
			//设置读取数据时间为30s
			conn.setReadTimeout(30000);
			out = new OutputStreamWriter(conn.getOutputStream());
			out.write(params);
			out.flush();
			in = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
			String line;
			while ((line = in.readLine()) != null) {
				result.append(line + "\n");
			}
		} catch (Exception e) {
			System.out.println("发送 POST 请求出现异常！" + e);
			e.printStackTrace();
		}
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
				if (conn != null) {
					conn.disconnect();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		if(result.length() <= 0){
			return null;
		}

		return result.toString();
	}


}
